package com.retail.lottery.colalottery.service.impl;

import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.retail.lottery.colalottery.entity.OrderCallback;
import com.retail.lottery.colalottery.enums.ErrorCodeEnum;
import com.retail.lottery.colalottery.enums.OrderCallbackStatusEnum;
import com.retail.lottery.colalottery.exception.BusinessException;
import com.retail.lottery.colalottery.service.OrderCallbackService;
import com.retail.lottery.colalottery.mapper.OrderCallbackMapper;
import com.retail.lottery.colalottery.utils.DateUtil;
import com.retail.lottery.colalottery.utils.MD5Util;
import com.retail.lottery.colalottery.utils.SignUtils;
import com.retail.lottery.colalottery.vo.request.OrderCallBackFormVo;
import com.retail.lottery.colalottery.vo.request.OrderCallBackVo;
import com.retail.lottery.colalottery.vo.response.OrderCallBackResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

/**
* @author jarvis.zhang
* @description 针对表【order_callback(三方渠道数据回传表)】的数据库操作Service实现
* @createDate 2025-06-06 13:38:38
*/
@Service
@Slf4j
public class OrderCallbackServiceImpl extends ServiceImpl<OrderCallbackMapper, OrderCallback>
    implements OrderCallbackService{

    @Value(value = "${cola-mtAppSecret}")
    private String appSecret;
    @Value(value = "${callback-targetUrl}")
    private String callbackHost;
    private static final Long timeGap = 10 * 60 * 1000L;

    @Override
    public OrderCallBackResponse orderDataPostBack(OrderCallBackVo orderCallBackVo) {
        OrderCallBackResponse response = new OrderCallBackResponse();
        String responseStr = JSONObject.toJSONString(orderCallBackVo);
        log.info("接收可乐订单回调数据,OrderCallBackVo:{}", responseStr);
        OrderCallback orderCallback = new OrderCallback();
        orderCallback.setEncryptMobile(orderCallBackVo.getEncryptMobile());
        orderCallback.setOrderCode(orderCallBackVo.getOrderId());
        orderCallback.setOrderCreateTime(Date.from(Instant.ofEpochSecond(orderCallBackVo.getOrderTime())));
        orderCallback.setOrderFinishTime(Date.from(Instant.ofEpochSecond(orderCallBackVo.getFinishTime())));
        orderCallback.setOrderStatus(orderCallBackVo.getOrderStatus());
        orderCallback.setSkuInfos(JSONObject.toJSONString(orderCallBackVo.getSkuInfos()));
        orderCallback.setActIdentifier(orderCallBackVo.getActIdentifier());
        orderCallback.setPlatformType(1);
        orderCallback.setRequestId(orderCallBackVo.getMt_request_id());
        int result = baseMapper.addColaOrderCallBack(orderCallback);
        if (result == 0) {
            log.info("接收可乐订单回调数据插入数据库失败：the data is {}", JSON.toJSONString(orderCallBackVo));
            throw new BusinessException(ErrorCodeEnum.DATABASE_ERROR);
        }
        log.info("接收可乐订单回调数据成功,OrderCallBackVo OrderId:{}", orderCallBackVo.getOrderId());
        response.setResult_code(OrderCallbackStatusEnum.all_ok.getCode());
        return response;
    }

    @Override
    public boolean checkMtSign(String path, OrderCallBackFormVo orderCallBack) {
        if (Objects.isNull(orderCallBack)
                || StringUtils.isBlank(orderCallBack.getSig())
                || StringUtils.isBlank(orderCallBack.getMt_request_id())
                || StringUtils.isBlank(orderCallBack.getApp_id())
                || Objects.isNull(orderCallBack.getTimestamp())) {
            log.error("order:{},参数错误,缺少系统性必传参数",orderCallBack);
            return false;
        }
        String orderId = orderCallBack.getOrderId();
        LocalDateTime time = Instant.ofEpochMilli(orderCallBack.getTimestamp())
                    .atZone(ZoneId.systemDefault())
                    .toLocalDateTime();
//        if(DateUtil.timeGap(time, LocalDateTime.now(), timeGap)){
//            log.error("orderId:{}参数错误,时间戳错误",orderId);
//            return false;
//        }
        Map<String, String> systemParams = convertSystemParamsToMap(orderCallBack);
        String systemParamsStr = concatParams(systemParams);

        Map<String, String> systemParams2 = convertSystemParamsToMap1(orderCallBack);
        String systemParamsStr2 = concatParams(systemParams2);

        try {
            //ed6cfe3389de3dacfe96b843980b65d0
            String signStr = callbackHost.concat(path).concat("?").concat(systemParamsStr).concat(appSecret);
            String md5 = MD5Util.getMD5(signStr);
            String sign = SignUtils.genSig(signStr);
            log.info("signStr:{}", signStr);
            log.info("sig:{}", orderCallBack.getSig());
            log.info("md5:{}", md5);
            log.info("sign {}",sign);
            String signStr2 = callbackHost.concat(path).concat("?").concat(systemParamsStr2).concat(appSecret);
            log.info("signStr2:{}", signStr2);
            String md52 = MD5Util.getMD5(signStr2);
            String sign2 = SignUtils.genSig(signStr2);
            log.info("md52:{}", md52);
            log.info("sign2 {}",sign2);
            boolean sigFlag = sign.equals(orderCallBack.getSig());
            log.info("orderId:{},checkMtSign-result: {}", orderId, sigFlag);
            return sigFlag;
        } catch (Exception e) {
            log.error("orderId:{},checkMtSign-exception", orderId, e);
            return false;
        }
    }

    private static String concatParams(Map<String, String> paramMap) {
        Object[] key_arr = paramMap.keySet().toArray();
        Arrays.sort(key_arr);
        String str = "";
        for(Object key : key_arr) {
            if (!key.equals("appSecret")) {
                String val = (String)paramMap.get(key);
                str = str + "&" + key + "=" + val;
            }
        }
        return str.replaceFirst("&", "");
    }

    public Map<String, String> convertSystemParamsToMap(OrderCallBackFormVo vo) {
        Map<String, String> map = new HashMap<>();
        //if (vo.getSig() != null)    map.put("sig", vo.getSig());
        if (vo.getFinishTime() != null) map.put("finishTime", vo.getFinishTime().toString());
        if (vo.getOrderTime() != null)  map.put("orderTime", vo.getOrderTime().toString());
        if (vo.getSkuList() != null)    map.put("skuList", vo.getSkuList());
        if (vo.getOrderId() != null)    map.put("orderId", vo.getOrderId());
        if (vo.getActIdentifier() != null)  map.put("actIdentifier", vo.getActIdentifier());
        if (vo.getOrderStatus() != null)    map.put("orderStatus", vo.getOrderStatus().toString());
        if (vo.getBrand_merchant_id() != null)  map.put("brand_merchant_id", vo.getBrand_merchant_id());
        if (vo.getEncryptMobile() != null)  map.put("brand_merchant_id", vo.getBrand_merchant_id());
        if (vo.getApp_id() != null) map.put("app_id", vo.getApp_id());
        if (vo.getMt_request_id() != null)  map.put("mt_request_id", vo.getMt_request_id());
        if (vo.getTimestamp() != null)  map.put("timestamp", vo.getTimestamp().toString());
        return map;
    }

    public Map<String, String> convertSystemParamsToMap1(OrderCallBackFormVo vo) {
        Map<String, String> map = new HashMap<>();
        if (vo.getApp_id() != null) map.put("app_id", vo.getApp_id());
        if (vo.getMt_request_id() != null)  map.put("mt_request_id", vo.getMt_request_id());
        if (vo.getTimestamp() != null)  map.put("timestamp", vo.getTimestamp().toString());
        return map;
    }


}




